//
// Created by dq550457 on 19-1-8.
//

#include <cstring>
#include "protocol.h"

uint8_t protocol::configNetworkCommand(const netConf * conf, char * out) {
    if(conf == nullptr) {
        return 0;
    }

    if(out == nullptr) {
        return 0;
    }
    out[0] = CONFIGN_NETWORK;

    //ssid
    out[1] = SSID_TOKEN;
    out[2] = conf->ssid_len;
    for(int i = 0; i < conf->ssid_len; i++) {
        out[3 + i] = conf->ssid[i];
    }

    //pwd
    out[3 + conf->ssid_len] = PASSWORD_TOKEN;
    out[4 + conf->ssid_len] = conf->pwd_len;
    for(int i = 0; i < conf->pwd_len; i++) {
        out[5 + conf->ssid_len + i] = conf->pwd[i];
    }

    //type
    out[5 + conf->ssid_len + conf->pwd_len] = Encryp_TOKEN;
    out[6 + conf->ssid_len + conf->pwd_len] = conf->encrypMode;
    return 7 + conf->ssid_len + conf->pwd_len;
}

uint8_t protocol::refreshCommand(char *out) {

    if(out == nullptr) {
        return 0;
    }

    out[0] = REFRSH;
    out[1] = 0x11;
    return 2;
}

uint8_t protocol::deviceStateCommand(deviceState * state, char *out) {

    if(out == nullptr) {
        return 0;
    }

    int index = 0;
    out[index++] = DEVICE_STATE;
    out[index++] = state->state;
    out[index++] = state->addr;
    return index;
}

uint8_t protocol::process(const void *inbuf, uint8_t len) {

    if(inbuf == nullptr) {
        return 0;
    }

    uint8_t * inIndex = (uint8_t *)inbuf;

    uint8_t ret = 0;

    switch (inIndex[0]) {
        case REFRSH:
            if(processRefresh(&inIndex[1], len - 1)) {
                ret = REFRSH;
            }
            break;
        case CONFIGN_NETWORK:
            if(processConfigNetwork(&inIndex[1], len - 1)) {
                ret = CONFIGN_NETWORK;
            }
            break;
        case DEVICE_STATE:
            if(processDeviceState(&inIndex[1], len - 1)) {
                ret = DEVICE_STATE;
            }
            break;
        default:
            break;
    }
    return ret;
}

bool protocol::processRefresh(const void *inbuf, uint8_t len) {
    if(inbuf == nullptr) {
        return false;
    }

    if(state == 1) {
        return false;
    }

    jclass clazz1 = env->FindClass("com/gree/syq/wifidemo/AirConditionRole");
    jmethodID getInstance = env->GetStaticMethodID(clazz1,"getInstance","(Landroid/content/Context;)Lcom/gree/syq/wifidemo/AirConditionRole;");
    jobject instance = env->CallStaticObjectMethod(clazz1,getInstance, nullptr);
    jmethodID onDeviceState = env->GetMethodID(clazz1,"onDeviceState","()V");
    env->CallVoidMethod(instance,onDeviceState);

    return true;
}

bool protocol::processConfigNetwork(const void *inbuf, uint8_t len) {
    if(inbuf == nullptr) {
        return false;
    }

    if(state == 1) {
        return false;
    }

    uint8_t out[1024] = {};

    uint8_t * inIndex = (uint8_t *)inbuf;

    netConf * pConf = (netConf *)out;

    if(inIndex[1] > 32) {
        return false;
    }
    pConf -> ssid_len = inIndex[1];
    memcpy(pConf->ssid,&inIndex[2],pConf -> ssid_len);

    if(inIndex[2 + pConf -> ssid_len] != PASSWORD_TOKEN) {
        return false;
    }

    if(inIndex[3 + pConf -> ssid_len] > 64) {
        return false;
    }
    pConf -> pwd_len = inIndex[3 + pConf -> ssid_len];
    memcpy(pConf->pwd,&inIndex[4 + pConf -> ssid_len],pConf -> pwd_len);

    pConf -> encrypMode = inIndex[len -1];

    char ssid[128] = {};
    char pwd[128]={};

    memcpy(ssid,pConf->ssid,pConf->ssid_len);
    memcpy(pwd,pConf->pwd,pConf->pwd_len);

    jclass clazz1 = env->FindClass("com/gree/syq/wifidemo/AirConditionRole");
    jmethodID getInstance = env->GetStaticMethodID(clazz1,"getInstance","(Landroid/content/Context;)Lcom/gree/syq/wifidemo/AirConditionRole;");
    jobject instance = env->CallStaticObjectMethod(clazz1,getInstance, nullptr);
    jmethodID setNetwork = env->GetMethodID(clazz1,"setNetworkNative","(Ljava/lang/String;Ljava/lang/String;I)V");
    env->CallVoidMethod(instance,setNetwork,env->NewStringUTF(ssid),env->NewStringUTF(pwd),pConf->encrypMode);

    return true;
}

bool protocol::processDeviceState(const void *inbuf, uint8_t len) {
    if(inbuf == nullptr) {
        return false;
    }

    if(state == 2) {
        return false;
    }


    uint8_t * inIndex = (uint8_t *)inbuf;
    uint8_t state = inIndex[0];
    uint8_t addr = inIndex[1];

    jclass clazz1 = env->FindClass("com/gree/syq/wifidemo/RemoteRole");
    jmethodID getInstance = env->GetStaticMethodID(clazz1,"getInstance","(Landroid/content/Context;)Lcom/gree/syq/wifidemo/RemoteRole;");
    jobject instance = env->CallStaticObjectMethod(clazz1,getInstance, nullptr);
    jmethodID onRefreshDevice = env->GetMethodID(clazz1,"onRefreshDeviceNative","(II)V");
    env->CallVoidMethod(instance,onRefreshDevice,state,addr);

    return true;
}
